package com.zenithmind.coding.controller;

import com.zenithmind.common.result.Result;
import com.zenithmind.coding.pojo.dto.CodeRunDTO;
import com.zenithmind.coding.pojo.vo.CodeRunResultVO;
import com.zenithmind.coding.service.CodeExecutionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

/**
 * 代码执行控制器
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Tag(name = "代码执行", description = "代码运行和调试相关接口")
@RestController
@RequestMapping("/api/zenithMind/v1/code")
@RequiredArgsConstructor
public class CodeExecutionController {

    private final CodeExecutionService codeExecutionService;

    @Operation(summary = "运行代码", description = "同步运行代码并返回结果")
    @PostMapping("/run")
    public Result<CodeRunResultVO> runCode(@Valid @RequestBody CodeRunDTO codeRunDTO) {
        CodeRunResultVO result = codeExecutionService.runCode(codeRunDTO);
        return Result.success(result);
    }

    @Operation(summary = "异步运行代码", description = "异步运行代码，返回运行ID")
    @PostMapping("/run/async")
    public Result<String> runCodeAsync(@Valid @RequestBody CodeRunDTO codeRunDTO) {
        String runId = codeExecutionService.runCodeAsync(codeRunDTO);
        return Result.success(runId);
    }

    @Operation(summary = "获取运行结果", description = "根据运行ID获取代码运行结果")
    @GetMapping("/run/{runId}")
    public Result<CodeRunResultVO> getRunResult(
            @Parameter(description = "运行ID") @PathVariable String runId) {
        CodeRunResultVO result = codeExecutionService.getRunResult(runId);
        return Result.success(result);
    }

    @Operation(summary = "停止代码运行", description = "停止正在运行的代码")
    @PostMapping("/run/{runId}/stop")
    public Result<Boolean> stopCodeRun(
            @Parameter(description = "运行ID") @PathVariable String runId) {
        Boolean result = codeExecutionService.stopCodeRun(runId);
        return Result.success(result);
    }

    @Operation(summary = "获取支持的编程语言", description = "获取平台支持的编程语言列表")
    @GetMapping("/languages")
    public Result<String[]> getSupportedLanguages() {
        String[] languages = codeExecutionService.getSupportedLanguages();
        return Result.success(languages);
    }

    @Operation(summary = "检查语言支持", description = "检查指定编程语言是否支持")
    @GetMapping("/languages/{language}/supported")
    public Result<Boolean> isLanguageSupported(
            @Parameter(description = "编程语言") @PathVariable String language) {
        Boolean supported = codeExecutionService.isLanguageSupported(language);
        return Result.success(supported);
    }

    @Operation(summary = "格式化代码", description = "格式化指定语言的代码")
    @PostMapping("/format")
    public Result<String> formatCode(
            @Parameter(description = "编程语言") @RequestParam String language,
            @Parameter(description = "源代码") @RequestBody String sourceCode) {
        String formattedCode = codeExecutionService.formatCode(language, sourceCode);
        return Result.success(formattedCode);
    }

    @Operation(summary = "分析代码质量", description = "分析代码质量并给出建议")
    @PostMapping("/analyze")
    public Result<CodeRunResultVO.CodeQualityAnalysis> analyzeCodeQuality(
            @Parameter(description = "编程语言") @RequestParam String language,
            @Parameter(description = "源代码") @RequestBody String sourceCode) {
        CodeRunResultVO.CodeQualityAnalysis analysis = codeExecutionService.analyzeCodeQuality(language, sourceCode);
        return Result.success(analysis);
    }

    @Operation(summary = "检测代码相似度", description = "检测两段代码的相似度")
    @PostMapping("/similarity")
    public Result<Double> detectCodeSimilarity(
            @Parameter(description = "编程语言") @RequestParam String language,
            @Parameter(description = "源代码1") @RequestParam String sourceCode1,
            @Parameter(description = "源代码2") @RequestParam String sourceCode2) {
        Double similarity = codeExecutionService.detectCodeSimilarity(language, sourceCode1, sourceCode2);
        return Result.success(similarity);
    }
}
